package com.ys.erp.framework.exception;


import com.ys.erp.framework.response.AbstractResponseCode;
import com.ys.erp.framework.response.ResponseDTO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * @author lwj
 * @date 2021/5/9
 */
@Slf4j
public abstract class BaseExceptionHandler {

    private static final String WARN_TITLE = "堆栈信息";

    /**
     * 参数校验异常处理（400异常）
     *
     * @param httpServletRequest 请求参数
     * @param e                  异常类信息
     * @return 统一异常信息
     */
    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseDTO<?> methodArgumentNotValidExceptionHandler(HttpServletRequest httpServletRequest, MethodArgumentNotValidException e) {
        String defaultMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        ResponseDTO<?> byError = ResponseDTO.createByError(AbstractResponseCode.VALID_ERROR.getCode(), defaultMessage, null);
        log.warn("MethodArgumentNotValidException 参数校验异常：{} \n 返回参数 {}", defaultMessage, byError);
        log.warn(WARN_TITLE, e);
        return byError;
    }

    /**
     * 参数校验异常处理（400异常）
     *
     * @param httpServletRequest 请求参数
     * @param e                  异常类信息
     * @return 统一异常信息
     */
    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(BindException.class)
    public ResponseDTO<?> bindingExceptionHandlerHandler(HttpServletRequest httpServletRequest, BindException e) {
        String defaultMessage = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        ResponseDTO<?> byError = ResponseDTO.createByError(AbstractResponseCode.VALID_ERROR.getCode(), defaultMessage, null);
        log.warn("BindException 参数校验异常：{} \n 返回参数 {}", defaultMessage, byError);
        log.warn(WARN_TITLE, e);
        return byError;
    }


    /**
     * 客户端请求方式异常处理（400异常）
     *
     * @param httpServletRequest 请求参数
     * @param e                  异常类信息
     * @return 统一异常信息
     */
    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public ResponseDTO<?> httpRequestMethodNotSupportedException(HttpServletRequest httpServletRequest, HttpRequestMethodNotSupportedException e) {
        ResponseDTO<?> responseErrorDTO = AbstractResponseCode.CLIENT_REQUEST_ERROR;
        log.warn("HttpRequestMethodNotSupportedException 客户端方式请求异常：{} \n 返回参数 {}", e.getMessage(), responseErrorDTO);
        log.warn(WARN_TITLE, e);
        return responseErrorDTO;
    }

    /**
     * 自定义业务异常处理（400异常）
     *
     * @param httpServletRequest 请求参数
     * @param e                  异常类信息
     * @return 统一异常信息
     */
    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(YsException.class)
    public ResponseDTO<?> baseBusinessExceptionHandler(HttpServletRequest httpServletRequest, YsException e) {
        ResponseDTO<?> responseErrorDTO = ResponseDTO.createByError(e.getCode(), e.getMessage(), null);
        log.warn("自定义业务异常处理：{} \n 返回参数 {}", e.getMessage(), responseErrorDTO);
        log.warn(WARN_TITLE, e);
        return responseErrorDTO;
    }

    /**
     * 其他Exception异常处理（500异常）
         *
         * @param httpServletRequest 请求参数
         * @param e                  异常类信息
         * @return 统一异常信息
     */
    @ResponseStatus(HttpStatus.OK)
    @org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class)
    public ResponseDTO<?> exceptionHandler(HttpServletRequest httpServletRequest, Exception e) {
        ResponseDTO<?> responseErrorDTO = ResponseDTO.createByError(HttpStatus.INTERNAL_SERVER_ERROR.value(), AbstractResponseCode.ERROR.getMessage(), null);
        log.error("Exception 未知异常处理：{} \n 返回参数 {}", e.getMessage(), responseErrorDTO);
        log.error(WARN_TITLE, e);
        return responseErrorDTO;
    }


}
